/*
 * ====================================================================
 * Copyright (c) 2002-2018 The RapidSVN Group.  All rights reserved.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program (in the file GPL.txt).
 * If not, see <http://www.gnu.org/licenses/>.
 *
 * This software consists of voluntary contributions made by many
 * individuals.  For exact contribution history, see the revision
 * history and logs, available at http://rapidsvn.tigris.org/.
 * ====================================================================
 */

// wxWidgets
#include "wx/wx.h"
#include "wx/utils.h"

// svncpp
#include "svncpp/client.hpp"
#include "svncpp/status_selection.hpp"

// app
#include "action.hpp"
#include "config.hpp"
#include "tracer.hpp"
#include "rapidsvn_app.hpp"
#include "utils.hpp"

// subversion api
#include "svn_wc.h"

#ifdef USE_SIMPLE_WORKER
void SafeYield()
{
  wxSafeYield();
}
#else
void SafeYield() {};
#endif

const unsigned int SvnAction::DONT_UPDATE          = 0x0001;
const unsigned int SvnAction::UPDATE_LATER         = 0x0002;
const unsigned int SvnAction::UPDATE_TREE          = 0x0004;

/*
 *
 */
SvnAction::SvnAction( MyTagApp* myTagApp, wxWindow * parent, const wxString & name, unsigned int _flags)
    :NormalAction( myTagApp, parent, name )
{
    this->flags = _flags;
  //m = new Data(parent, name, flags);
    context = nullptr;
}

SvnAction::~SvnAction()
{
  //delete m;
  delete tracer;
}

void SvnAction::SetParent(wxWindow * _parent)
{
  parent = _parent;
}

void SvnAction::SetPath(const svn::Path & _path)
{
  path = _path;
}

const svn::Path &SvnAction::GetPath()
{
  return path;
}

void SvnAction::SetSvnContext(svn::Context * context)
{
  this->context = context;
}

svn::Context *SvnAction::GetSvnContext()
{
  return context;
}

void SvnAction::SetStatusSel(const svn::StatusSel & _statusSel)
{
  this->statusSel = _statusSel;
}

const svn::StatusVector &SvnAction::GetStatusVector() const
{
  return statusSel.statusVector();
}

const svn::Targets &SvnAction::GetTargets() const
{
  return statusSel.targets();
}

/*
 *
 */
bool SvnAction::Prepare()
{
  const wxString & dir = Utf8ToLocal( path.c_str());
  if (!dir.empty()) {
    size_t index = dir.find("://");
    if (index == wxNOT_FOUND)
      wxSetWorkingDirectory(dir);
  }

  return true;
}

svn::Path SvnAction::GetTarget() const
{
  return statusSel.target();
}
/*
const wxString &SvnAction::GetName() const
{
  return name;
}*/
/*
void SvnAction::SetName(const wxString & name)
{
  m->name = name;
}*/

unsigned int SvnAction::GetFlags() const
{
  return flags;
}

svn::Path SvnAction::GetPathAsTempFile(const svn::Path & path,
                                       const svn::Revision & revision)
{
  svn::Client client(GetSvnContext());

  svn::Revision peg_revision;
  if (path.isUrl())
    peg_revision = svn::Revision::HEAD;
  else
    peg_revision = svn::Revision::BASE;

  wxString revStr;
  if (revision.kind() == svn::Revision::HEAD)
    revStr = _("HEAD");
  else if (revision.kind() == svn::Revision::BASE)
    revStr = _("BASE");
  else if (revision.kind() == svn::Revision::PREVIOUS)
    revStr = _("PREVIOUS");
  else
    revStr.Printf(wxT("%") wxT(SVN_REVNUM_T_FMT), revision.revnum());

  wxString msg, wxPath(Utf8ToLocal(path.c_str()));
  msg.Printf(_("Get file %s rev. %s"),
             wxPath.c_str(), revStr.c_str());
  Trace(msg);

  svn::Path dstPath("");
  client.get(dstPath, path, revision, peg_revision);

  // Remember this temporary file so we can delete it when the application exits
  ::wxGetApp().OptionallyRegisterTempFile(
    Utf8ToLocal(dstPath.c_str()));

  return dstPath;
}

const svn::StatusSel &SvnAction::GetStatusSel() const
{
  return statusSel;
}

void SvnAction::SetName(const wxString &name) {
    this->name = name;
}

/* -----------------------------------------------------------------
 * local variables:
 * eval: (load-file "../rapidsvn-dev.el")
 * end:
 */

bool NormalAction::Prepare() {
    return false;
}

bool NormalAction::Perform() {
    return false;
}

NormalAction::NormalAction( MyTagApp* _myTagApp, wxWindow * parent, const wxString & _name  ) {
    this->myTagApp = _myTagApp;
    this->name = _name;
    //wxString t = _name;
    //this->name = t;
    this->parent = parent;
    this->flags = 0;
}

wxWindow *NormalAction::GetParent() {
    return parent;
}

void NormalAction::SetTracer(Tracer * t, bool own)
{
    tracer = t;
    ownTracer = own;
}

Tracer *NormalAction::GetTracer()
{
    return tracer;
}

//
void NormalAction::Trace(const wxString & msg)
{
    if ( this->tracer  )
    {
        tracer->Trace(msg);
    }
    SafeYield();
}

void NormalAction::TraceError(const wxString & msg)
{
    if (tracer)
    {
        tracer->TraceError(msg);
    }

    SafeYield();
}